package com.douxg.learning.worktest.yxaq.dp;


import com.ai.aus.dataprocess.comm.Event;
import com.ai.aus.dataprocess.comm.PluginContext;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.JedisCommands;

import java.io.InputStream;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @ProjectName: aus-plugin-DataCompletion
 * @Package: PACKAGE_NAME
 * @ClassName: DataCompletion
 * @Description: 阜外医院补全位置信息
 * @Author: du
 * @CreateDate: 2019/11/8 17:43
 * @Version: 1.0
 */
public class DataCompletion {

    private static final Logger logger = LoggerFactory.getLogger(DataCompletion.class);
    private static Set<Integer> ipRangeCodeSet = new HashSet<Integer>();
    private static ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);

    /**
     * 初始化
     *
     * @return
     */
    public boolean initialize(PluginContext pluginContext) {
        logger.info("DataCompletion plugin init..");
        boolean flag = false;
        Properties pps = new Properties();

        try {
            logger.info("DataCompletion init success");
            InputStream in = DataCompletion.class.getProtectionDomain().getClassLoader().getResourceAsStream("application.properties");
//            InputStream in = new BufferedInputStream(new FileInputStream("config/application.properties"));
            pps.load(in);
            String ip = pps.getProperty("spring.redis.host").trim();
            String password = pps.getProperty("spring.redis.password");
            int port = Integer.parseInt(pps.getProperty("spring.redis.port"));
            int timeout = Integer.parseInt(pps.getProperty("spring.redis.timeout"));
            int maxActive = Integer.parseInt(pps.getProperty("spring.redis.maxActive"));
            int maxIdle = Integer.parseInt(pps.getProperty("spring.redis.maxIdle"));
            int maxWait = Integer.parseInt(pps.getProperty("spring.redis.maxWait"));
            RedisUtil.poolInit(ip, password, port, timeout, maxActive, maxIdle, maxWait);
//            ipRangeCodeGet();
            scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
                public void run() {
                    ipRangeCodeGet();
                }
            }, 0, 15, TimeUnit.SECONDS);
        } catch (Exception e) {
            logger.error("Exception:", e);
        }

        return flag;
    }

    private void ipRangeCodeGet() {
        System.out.println("ipRangeCodeGet***************start," + System.currentTimeMillis());
        JedisCommands jedisCommands = RedisUtil.getJedis();
        Set<String> set = null;
        try {
            set = jedisCommands.smembers("POL_FW_IP_RANGE_CODE");
        } catch (Exception e) {
            logger.error("redis error", e);
        } finally {
            RedisUtil.close(jedisCommands);
        }
        if (set != null && set.size() > 0) {
            Set<Integer> ipRangeCodes = new HashSet<Integer>();
            for (String s : set) {
                ipRangeCodes.add(Integer.parseInt(s));
            }
            ipRangeCodeSet = ipRangeCodes;
        }
        System.out.println("ipRangeCodeGet***************end," + ipRangeCodeSet + "," + System.currentTimeMillis());
    }

    /**
     *
     */
    public List<Event> processMsg(List<Event> list) throws Exception {
        logger.info("DataCompletion processMsg start...");
        for (Event event : list) {
            Map<String, String> parserFieldContent = event.getParserFieldContent();
            if (parserFieldContent != null) {
                if (parserFieldContent.containsKey("SRC_IP")) {
                    String ip = parserFieldContent.get("SRC_IP");
                    handleAssetIpPosition(parserFieldContent, ip, "SRC_POSITION");
                }
                if (parserFieldContent.containsKey("DST_IP")) {
                    String ip = parserFieldContent.get("DST_IP");
                    handleAssetIpPosition(parserFieldContent, ip, "DST_POSITION");
                }

            }
        }
        logger.info("DataCompletion processMsg end...");
        return list;
    }

    /**
     * 处理资产对应位置
     */
    private void handleAssetIpPosition(Map<String, String> parserFieldContent, String ip, String key) {
        //logger.info(parserFieldContent.toString());
        //logger.info("ip:{}", ip);
        JedisCommands jedisCommands = RedisUtil.getJedis();
        try {
            String position = jedisCommands.hget("POL_FW_ASSET_IP_POSITION", ip);
            //logger.info("position:{}", position);
            if (StringUtils.isNotBlank(position)) {
                parserFieldContent.put(key, position);
            } else {
                List<String> keys = new ArrayList<String>();
                for (Integer type : ipRangeCodeSet) {
                    int i = ipNetCode(ip, type);
                    keys.add(i + "");
                }
                if (keys.size() == 0) {
                    return;
                }
                List<String> hmget = jedisCommands.hmget("POL_FW_IP_RANGE", keys.toArray(new String[0]));
                System.out.println("key=" + keys + ",value=" + hmget);
                if (hmget != null) {
                    for (String s : hmget) {
                        if (StringUtils.isNotBlank(s)) {
                            parserFieldContent.put(key, s);
                            break;
                        }
                    }
                }
            }
        } finally {
            RedisUtil.close(jedisCommands);
        }
        //logger.info(parserFieldContent.toString());
    }

    public boolean notifyFinish() {

        return true;
    }

    public void rollBack() {

    }

    public void checkSync() {

    }

    public static int ipNetCode(String ip, int type) {
        String[] ips = ip.split("\\.");
        int ipAddr = (Integer.parseInt(ips[0]) << 24)
                | (Integer.parseInt(ips[1]) << 16)
                | (Integer.parseInt(ips[2]) << 8) | Integer.parseInt(ips[3]);
        int mask = 0xFFFFFFFF << (32 - type);
        return ipAddr & mask;
    }

    public static void main(String[] args) {
        String ip = "10.101.2.36";
        String ip2 = "10.101.2.37";
        int types[] = {16, 24, 25, 32};
        for (int type : types) {
            System.out.println(ipNetCode(ip, type));
        }
    }
}
